`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:School of Information Seience and Technology, Southeast university
// Engineer: justice_wing;cooper zhang
// 
// Create Date: 2018/03/05 16:37:41
// Design Name: POC of COA
// Module Name: POC_design
// Project Name:  
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module POC_design(IRQ,CLK,RW,MODE,Din,Dout,ADDR,RST);
input  RST;
input  CLK;
input  RW;
input  [1:0]ADDR;
input  [7:0]Din;
//input  RDY;
input  MODE;
//output [7:0]PD;
output [7:0]Dout;
//output TR;
output IRQ;

//wire  MODE_wire;
reg [7:0]PD;
reg TR;
wire RDY;
//wire [7:0]PD;
//wire TR;
//wire [1:0]ADDR_wire;
//wire [7:0]Din_wire;
reg [7:0] Dout;
reg IRQ;
reg [7:0] SR;
reg [7:0] BR;

parameter select_BR = 2'b01;
parameter select_SR = 2'b10;
parameter enable_IRQ  = 1'b0;
parameter disable_IRQ = 1'b1;
parameter enable_TR  = 1'b1;
parameter disable_TR = 1'b0;
parameter poll_MODE = 1'b1;
parameter iret_MODE =1'b0;
parameter read_RW  = 1'b0;
parameter write_RW = 1'b1;

PRINTER_design printer
					  (
					   .printer_RDY(RDY),
					   .printer_TR(TR),
					   .printer_PD(PD),
					   .CLK(CLK)
					  );

initial
begin
	PD  = 8'b0000_0000;
	Dout= 8'b0000_0000;
	SR = 8'b0000_0000;
	BR = 8'b0000_0000;
	TR = 1'b0;
	IRQ = 1'b1;
end

always@(posedge CLK)
begin
	if(RST == 0)
	begin
		PD  <= 8'b0000_0000;
		Dout<= 8'b0000_0000;
		SR <= 8'b1000_0000;
		BR <= 8'b0101_1010;
		TR <= 1'b0;
		IRQ <= 1'b1;
	end
	else if(MODE == poll_MODE)  //polling mode
	begin
		if(ADDR == select_SR && RW == read_RW)
		begin
			if(SR[7] == 0 && RDY ==1 && TR == 0)
			begin
				PD <= BR;
				TR <= enable_TR;
				Dout <= SR;
				
			end
			else if(TR == 1)
			begin
				TR <= disable_TR;
				SR[7] <= 1'b1;
				Dout <= SR;
			end
			else
			begin
				Dout <= SR;
			end
		end
		if(ADDR == select_SR && RW == write_RW)
		begin
			SR <= Din;
		end
		if(ADDR == select_BR && RW == write_RW)
		begin
			if(SR[7] == 1 && RDY == 1 && TR == 0)
			begin
				BR <= Din;
//				PD <=BR;
//				TR <= 1'b1;
                SR[7] <=0;
				Dout <= 8'b0000_0000;	
			end
//			else if(TR == 1)
//			begin
//				TR = disable_TR;
//				SR[7] <= 1'b0;
//				BR <= Din;
//				Dout <= 8'b0000_0000;
//			end
//			else 
//			begin
//				BR <= Din;
//				Dout <= 8'b0000_0000;
//				SR[7] <= 1'b0;
//				TR <= 1'b1;
//			end
		end
	end
	else if(MODE == iret_MODE)		//interrupt mode
	begin
		if(SR[0] == 0)
		begin
		SR <= 8'b0000_0001;
		end
		if(ADDR == select_SR && RW == read_RW)
		begin
			if(SR[7] == 0 && RDY == 1 && TR == disable_TR)
			begin
				PD <= BR;
				TR <= enable_TR;
				IRQ <= enable_IRQ;
				Dout <= SR;
			end
			else if( TR == enable_TR)
			begin
				TR <= disable_TR;
				IRQ <= disable_IRQ;
				SR[7] <= 1;
				Dout <= SR;
			end
			else 
			begin
				Dout <=SR;
				IRQ <= enable_IRQ;
			end
		end
		if(ADDR == select_SR && RW == write_RW)
		begin
			SR <= Din;
		end
		if(ADDR == select_BR && RW == write_RW)
		begin
			if(SR[7] == 0 && RDY == 1 && TR == 0)
			begin
				BR <= Din;
				PD <= BR;
				TR <= enable_TR;
				IRQ <= enable_IRQ;
				Dout <= 8'b0000_0001;
			end
			else if(TR == enable_TR)
			begin
				TR <= disable_TR;
				IRQ <= disable_IRQ;
				SR[7] <= 1'b1;
				BR <= Din;
				Dout <= 8'b0000_0001;
			end
			else
			begin
				BR <= Din;
				IRQ <= enable_IRQ;
				Dout <= 8'b0000_0001;
			end
		end
	end
end

endmodule
